package com.xms.web.framework.filter;

import com.xms.core.annotation.AllowAnonymous;
import com.xms.core.annotation.Description;
import com.xms.logging.entity.VisitedLog;
import com.xms.logging.service.IVisitedLogService;
import com.xms.security.entity.Privilege;
import com.xms.security.identity.ICurrentUser;
import com.xms.security.service.sitemap.IPrivilegeFinderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * <p>
 * 日志记录拦截器
 * </p>
 *
 * @author migo
 * @since 2021/8/28
 */
@Component
public class ActionLoggingInterceptor implements HandlerInterceptor {
    private IVisitedLogService _visitedlogService;
    private ICurrentUser _currentUser;
    private IPrivilegeFinderService _privilegeFinderService;
    @Autowired
    public ActionLoggingInterceptor(IVisitedLogService visitedlogService,
                                    ICurrentUser currentUser,
                                    IPrivilegeFinderService privilegeFinderService){
        _visitedlogService = visitedlogService;
        _currentUser = currentUser;
        _privilegeFinderService = privilegeFinderService;
    }

    @Override
    public boolean preHandle(HttpServletRequest httpRequest, HttpServletResponse httpResponse, Object o) throws Exception {
        if(!(o instanceof HandlerMethod)){
            return true;
        }
        boolean allowAnnoymous = ((HandlerMethod) o).getBean().getClass().isAnnotationPresent(AllowAnonymous.class);
        if(!allowAnnoymous){
            allowAnnoymous = ((HandlerMethod) o).getMethod().isAnnotationPresent(AllowAnonymous.class);
        }
        if(allowAnnoymous){
            return true;
        }
        String path = httpRequest.getRequestURI();
        // 如果访问登录页面或者静态资源则跳过
        if(path.indexOf("/signin") >= 0 || path.indexOf("/error") >= 0 || path.indexOf("/content/") >= 0){
            return true;
        }
        if(_currentUser.getUser() == null) return true;
        //获取控制器的名字
        String controllerName = ((HandlerMethod) o).getBean().getClass().getSimpleName();
        //获取方法名
        Method actionMethod = ((HandlerMethod) o).getMethod();
        //方法注解中的描述文字
        Description descAnno = actionMethod.getAnnotation(Description.class);
        String actionName = actionMethod.getName();
        Privilege prv = _privilegeFinderService.getByName("", controllerName, actionName);
        VisitedLog entity = new VisitedLog();
        entity.setLoglevel(1);
        entity.setTitle(prv != null ? prv.getDisplayname() : (descAnno != null ? descAnno.value() : ""));
        if(entity.getTitle().isEmpty()){
            entity.setTitle(controllerName + "." + actionName);
        }
        entity.setUrl(path);
        entity.setUrlreferrer(httpRequest.getHeader("Referer"));
        entity.setSystemuserid(_currentUser.getUser().SystemUserId);
        entity.setStatuscode(httpResponse.getStatus());
        entity.setClientip(httpRequest.getRemoteAddr());
        entity.setCreatedon(LocalDateTime.now());
        entity.setOrganizationid(_currentUser.getUser().OrganizationId);
        _visitedlogService.save(entity);

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
